/*
 * DataToDevice.cuh
 *
 *  Created on: Sep 16, 2013
 *      Author: jaime
 */

#ifndef DATATODEVICE_CUH_
#define DATATODEVICE_CUH_

#include "../Utils/GPUVec.cuh"
#include "../Utils/CUDAClauseVec.cuh"
#include "JobsQueue.cuh"
#include "../Statistics/RuntimeStatistics.cuh"
#include "Results.cuh"
#include "../JobsManager/JobChooser.cuh"
#include "../BCPStrategy/WatchedClausesList.cuh"
#include "../ErrorHandler/CudaMemoryErrorHandler.cuh"
#include "../Utils/NodesRepository.cuh"
#include "../FileManager/FormulaData.cuh"

class DataToDevice {
public:
	DataToDevice(CUDAClauseVec clauses_database,
			int number_of_variables, int number_of_clauses, int number_of_jobs,
			int number_of_blocks, int number_of_threads,
			int max_implication_per_var,
			GPUVec<Var> dead_vars);
//	DataToDevice(FormulaData data, int number_of_jobs, int number_of_blocks,
//			int number_of_threads, int max_implication_per_var, GPUVec<Var> dead_vars);


	void prepare_sequencial();
	void prepare_parallel(JobChooser & chooser
#ifdef ASSUMPTIONS_USE_DYNAMICALLY_ALLOCATED_VECTOR
		, GPUVec<Lit> & assumptions
#endif
	);

#ifdef ASSUMPTIONS_USE_DYNAMICALLY_ALLOCATED_VECTOR
	__device__ GPUVec< GPUVec<Lit> > get_all_assumptions_parallel();
	__device__ GPUVec<Lit> get_assumptions_sequential();
#endif

	__host__ __device__ JobsQueue get_jobs_queue();
	__host__ __device__ CUDAClauseVec get_clauses_db();
	__host__ __device__ CUDAClauseVec * get_clauses_db_ptr();
	__host__ __device__ int get_number_of_variables();
	__host__ __device__ int get_max_implication_per_var();
	__host__ __device__ GPUVec<Var> get_dead_vars();
#ifdef ENABLE_STATISTICS
	__host__ __device__ RuntimeStatistics get_statistics();
	__host__ __device__ RuntimeStatistics * get_statistics_ptr();
#endif
	__host__ __device__ unsigned int * get_found_answer_ptr();
	__host__ __device__ Results get_results();
	__host__ __device__ Results* get_results_ptr();
	__host__ __device__ NodesRepository<GPULinkedList<WatchedClause*>::Node>*
	get_nodes_repository_ptr();
	//__device__ GPUVec <WatchedClause> get_watched_clauses(int thread_block_index);

private:
	CUDAClauseVec clauses_db;
	int number_of_variables;
#ifdef ASSUMPTIONS_USE_DYNAMICALLY_ALLOCATED_VECTOR
	GPUVec< GPUVec<Lit> > all_assumptions_parallel;
	GPUVec<Lit> assumptions_sequential;
#endif
	JobsQueue queue;
	unsigned int* found_answer;
#ifdef ENABLE_STATISTICS
	RuntimeStatistics statistics;
#endif
	Results results;
	int max_implication_per_var;
	GPUVec <Var> dead_vars;
	int number_of_thread;
	int number_of_blocks;

	//GPUVec< GPUVec < WatchedClause > > watched_clauses_per_thread;
	NodesRepository<GPULinkedList<WatchedClause*>::Node> nodes_repository;


};

#endif /* DATATODEVICE_CUH_ */
